package com.framework.modules.base.controller;

import java.math.BigDecimal;
import java.util.*;

import cn.hutool.dfa.SensitiveUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.framework.common.annotation.Login;
import com.framework.common.annotation.SensitiveFilter;
import com.framework.common.config.SystemConfigName;
import com.framework.common.consts.RedisConstKey;
import com.framework.common.live.TencentLiveKit;
import com.framework.common.message.MessagePacketData;
import com.framework.common.message.MessageType;
import com.framework.common.model.config.ConfigAgoraSdk;
import com.framework.common.model.config.ConfigJuheSdk;
import com.framework.common.model.config.ConfigPaymentRateMoney2Coin;
import com.framework.common.model.config.ConfigServers;
import com.framework.common.oss.CloudStorageService;
import com.framework.common.oss.OSSFactory;
import com.framework.common.utils.*;
import com.framework.common.validator.ValidatorUtils;
import com.framework.form.RegisterForm;
import com.framework.modules.app.entity.MixedOnlineUserEntity;
import com.framework.modules.app.service.MixedOnlineUserService;
import com.framework.modules.base.entity.*;
import com.framework.modules.base.service.*;
import com.framework.modules.chat.service.ChatFriendService;
import com.framework.modules.dataview.entity.ViewUserInfoSpaceEntity;
import com.framework.modules.dataview.service.*;
import com.framework.modules.live.entity.LiveRoomEntity;
import com.framework.modules.live.service.LiveRewardsService;
import com.framework.modules.live.service.LiveRoomService;
import com.framework.modules.user.entity.PhotosEntity;
import com.framework.modules.user.entity.UserBankEntity;
import com.framework.modules.user.entity.UserWithdrawHistoryEntity;
import com.framework.modules.user.service.PhotosService;
import com.framework.modules.user.service.UserBankService;
import com.framework.modules.user.service.UserWithdrawHistoryService;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.DependsOn;
import org.springframework.web.bind.annotation.*;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.multipart.MultipartFile;



/**
 * 用户
 *
 * @author MIT
 * @email litmiss@gmail.com
 * @date 2020-10-20 18:11:40
 */
@RestController
@RequestMapping("/user")
@DependsOn("databaseInitConfig")
@Api(tags = "用户接口")
public class UserController {

    protected Logger logger = LoggerFactory.getLogger(getClass());


    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private UserService userService;


    @Autowired
    private PostsService postsService;

    @Autowired
    private UserLocationService userLocationService;

    @Autowired
    private UserReportService userReportService;

    @Autowired
    private UserSpaceService userSpaceService;

    @Autowired
    private ViewUserInfoSpaceService viewUserInfoSpaceService;

    @Autowired
    private UserOrderService userOrderService;

    @Autowired
    private ValidateCodeService validateCodeService;

    @Autowired
    private LiveRoomService liveRoomService;

    @Autowired
    private UserVipinfoService userVipinfoService;

    @Autowired
    private LiveRewardsService liveRewardsService;

    @Autowired
    private PhotosService photosService;

    @Autowired
    private ChatFriendService chatFriendService;

    @Autowired
    private UserPolicySettingService userPolicySettingService;

    @Autowired
    private UserDoingService userDoingService;


    @Autowired
    private ViewChatFriendListService viewChatFriendListService;

    @Autowired
    private ViewChatFriendForTargetListService viewChatFriendForTargetListService;

    @Autowired
    private ViewUserDoingGroupListService viewUserDoingGroupListService;

    @Autowired
    private ViewUserDoingGroupForObjectListService viewUserDoingGroupForObjectListService;

    @Autowired
    private ViewUserGiftListService viewUserGiftListService;

    @Autowired
    private UserBankService userBankService;

    @Autowired
    private UserWithdrawHistoryService userWithdrawHistoryService;

    @Autowired
    private UserIncomeHistoryService userIncomeHistoryService;

    @Autowired
    private ViewUserPostsListService viewUserPostsListService;

    @Autowired
    private UserBalanceService userBalanceService;

    @Autowired
    private UserPaymentService userPaymentService;

    @Autowired
    private MixedOnlineUserService mixedOnlineUserService;

    @Autowired
    private IdcardVerifyHistoryService idcardVerifyHistoryService;


    @Autowired
    private RedisUtils redisUtils;

    /**
     * 获取当前用户基本信息
     * 通过当前的 token 识别用户ID，并查询出用户信息
     * 关联表 tb_user , tb_user_info，tb_user_balance
     * @param type 用户信息类型, full 为全部信息,base基础tb_user表信息,info为tb_user_info信息，balance为tb_user_balance信息
     * @return
     */
    @Login
    @GetMapping("/info")
    @ApiOperation("获取用户基本信息")
    public R info(String type){
        Long uid=(Long)HttpContextUtils.getHttpServletRequestHeaderValue(HttpContextUtils.USER_KEY);
        //根据token查询用户的基本信息
        Object object=userInfoService.getInfo(uid,type);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok(object);
    }

    /**
     *补全注册信息
     * 数据库 [ 用户信息表 ] tb_user_info
     * @param userInfoEntity
     * @return
     */
    @Login
    @SensitiveFilter
    @PostMapping("/save_register_info")
    @ApiOperation("补全注册信息")
    public R saveRegisterInfo(UserInfoEntity userInfoEntity){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        //校验ibo和名字是否包含敏感词
        if(SensitiveUtil.containsSensitive(userInfoEntity.getIbo())){
            return R.error("用户签名包含敏感词！");
        }
        if(SensitiveUtil.containsSensitive(userInfoEntity.getNickname())){
            return R.error("用户名包含敏感词！");
        }

        //更新注册信息
        Object object=userInfoService.saveRegisterInfo(uid,userInfoEntity);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok("保存成功");
    }


    /**
     * 更新头像
     * @param avatar 为头像url地址，需先调用上传文件接口获得
     * @return
     */
    @Login
    @PostMapping("/update_avatar")
    @ApiOperation("更新头像")
    public R updateAvatar(String avatar){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");if(StringUtils.isBlank(avatar)){
            return R.ok("请上传一个文件");
        }
        UserInfoEntity userInfoEntity=new UserInfoEntity();
        userInfoEntity.setUid(uid.intValue());
        userInfoEntity.setAvanta(avatar);

        Object object=userInfoService.updateUserInfo(userInfoEntity);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok("保存成功");
    }


    /**
     * 上传文件
     * @param file 文件对象
     * @param type 文件的类型，avatar,post,video,images,temp,test
     * @return 返回 oss url
     */
    @Login
    @PostMapping("/upload")
    @ApiOperation("上传文件")
    public R upload(@RequestParam("file") MultipartFile file,String type) {

        if (type.isEmpty()) {
            return R.error(-1, "请选择一个文件类型");
        }

        Map<String, Object> maps = QuickHelper.getClassFiledsMap(OSSFactory.DirectoryConfig);

        if (!maps.containsKey(type)) {
            return R.error(-1, "请选择一个文件类型不合法");
        }
        if (file == null) {
            return R.error(-1, "请选择一个文件");
        }
        Map<String,Object> subInfo= (Map<String, Object>) maps.get(type);
        try {
            CloudStorageService service = OSSFactory.create();
            String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            String path = QuickHelper.createCloudStorageFileName(suffix,subInfo.get("value").toString());
            String url = service.upload(file.getBytes(), path).getUrl();
            return R.ok("调用完成，并入库").put("url", url);
        } catch (Exception e) {
            return R.error("上传失败：" + e.getMessage());
        }
    }

    /**
     * 发布动态
     * 动态 content 字段的的格式，方便前后端反序列化
     * 1、type = post 纯文字
     * content = {
     *   text : ""
     * }
     * 2、type = image 带图片的
     * content = {
     *   "text" : "",
     *   "media" : [图片1,图片2,...]
     * }
     * 3、type = video 带视频的
     * content = {
     *   "text" : "",
     *   "media" : [视频1]
     * }
     * [ 用户动态 ] tb_posts
     * @param postsEntity 文件对象 type类型 post,video ;view_policy隐私设置 公开=public,私人=private,好友=friend,不感兴趣的人=stranger
     * @return 返回成功
     */
    @Login
    @PostMapping("/post_item_add")
    @ApiOperation("发布动态")
    public R postItemAdd(PostsEntity postsEntity){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        //校验敏感词内容
        String content=postsEntity.getContent();
        JSONObject jsonObject=JSONObject.parseObject(content);
        if(jsonObject.containsKey("text")){
            if(SensitiveUtil.containsSensitive(jsonObject.getString("text"))){
                return R.error("发布的内容有敏感词！");
            }
        }
        Map<String, Object> maps = QuickHelper.getClassFiledsMap(OSSFactory.DirectoryConfig);
        if (!maps.containsKey(postsEntity.getType())) {
            return R.error(-1, "type参数错误");
        }

        Object object=postsService.postItemAdd(uid,postsEntity);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok("发布成功");
    }

    /**
     * 管理动态
     * [ 用户动态 ] tb_posts
     * @param postsEntity 文件对象 目前只支持 view_policy 隐私设置字段 隐私设置 公开=public,私人=private,好友=friend,不感兴趣的人=stranger
     * @return 返回成功
     */
    @Login
    @PostMapping("/post_item_mod")
    @ApiOperation("管理动态")
    public R postItemMod(PostsEntity postsEntity){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        Object object=postsService.postItemMod(uid,postsEntity);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok("修改成功");
    }


    /**
     * 删除动态
     * [ 用户动态 ] tb_posts
     * @param pid 用户动态id
     * @return 返回成功
     */
    @Login
    @PostMapping("/post_item_delete")
    @ApiOperation("删除动态")
    public R postItemDelete(Integer pid){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        Object object=postsService.postItemDelete(uid,pid);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok("删除成功");
    }

    /**
     * 我的动态
     * [ 我的动态 ] tb_posts
     * @return 返回成功
     */
    @Login
    @GetMapping("/posts")
    @ApiOperation("我的动态")
    public R posts(Integer page){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        Map<String,Object> paramMap=new HashMap<>();
        paramMap.put("page",page.toString());
        paramMap.put("limit",QuickHelper.getConfigString(SystemConfigName.RECORD_POST_PAGE_COUNT));
        paramMap.put("state",1);
        paramMap.put("uid",uid);
        PageUtils pageUtils=viewUserPostsListService.queryPage(paramMap);
        return R.ok(pageUtils);
    }

    /**
     * 更新个人资料
     * [ 更新个人资料 ] tb_user_info
     * 更新个人资料页面，友街id不可更新,昵称不可重复，性别，男=1,女=0
     * @return 返回成功
     */
    @Login
    @PostMapping("/update_user_info")
    @ApiOperation("更新个人资料")
    public R updateUserInfo(UserInfoEntity userInfoEntity){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        if(null==userInfoEntity){
            return R.response(ResponseCode.FAIL,"没有更改内容");
        }
        //校验ibo和名字是否包含敏感词
        if(SensitiveUtil.containsSensitive(userInfoEntity.getIbo())){
            return R.error("用户签名包含敏感词！");
        }
        if(SensitiveUtil.containsSensitive(userInfoEntity.getNickname())){
            return R.error("用户名包含敏感词！");
        }
        if(SensitiveUtil.containsSensitive(userInfoEntity.getSchool())){
            return R.error("内容包含敏感词！");
        }

        Object object=userInfoService.saveUserInfo(uid,userInfoEntity);
        if(object instanceof String){
            return R.response(ResponseCode.FAIL,object.toString());
        }
        return R.ok("修改成功");
    }

    /**
     * 喜欢动态
     * [ 喜欢动态] tb_posts ，tb_user_doing
     * @param postUid 动态对象Uid
     * @param postId 动态id
     * @return 返回成功 result true=喜欢 false=非喜欢
     */
    @Login
    @PostMapping("/post_item_like")
    @ApiOperation("喜欢动态")
    public R postItemLike(Integer postUid,Integer postId){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        UserDoingEntity userDoingEntity=new UserDoingEntity();
        userDoingEntity.setUid(uid.toString());
        //对象名称 user,post,comment
        userDoingEntity.setObjectName("post");
        userDoingEntity.setObjectId(postId);
        userDoingEntity.setObjectUid(postUid.toString());
        userDoingEntity.setType("like");
        Object object=postsService.likePosts(userDoingEntity);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok("操作成功").put("result",object);
    }

    /**
     * [ 关注用户] tb_user_space ，tb_user_doing
     * @param attendUid
     * @return result = true 已关注 false 已取消
     */
    @Login
    @PostMapping("/attent")
    @ApiOperation("关注用户")
    public R attent(Integer attendUid){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        if(uid==null||null==attendUid||uid.equals(attendUid)){
            return R.error("关注失败");
        }
        if(uid.intValue()==attendUid.intValue()){
            return R.error("无法关注自己");
        }
        UserDoingEntity userDoingEntity=new UserDoingEntity();
        userDoingEntity.setUid(uid.toString());
        //对象名称 user,post,comment
        userDoingEntity.setObjectName("user");
        userDoingEntity.setObjectId(attendUid);
        userDoingEntity.setObjectUid(attendUid.toString());
        userDoingEntity.setType("attent");
        userDoingEntity.setUid(uid.toString());
        Object object=userSpaceService.attentUser(userDoingEntity);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok("操作成功").put("result",object);
    }

    /**
     * [ 喜欢用户] tb_user_space ，tb_user_doing
     * @param likeUid
     * @return result = true 已关注 false 已取消
     */
    @Login
    @PostMapping("/like_user")
    @ApiOperation("喜欢用户")
    public R likeUser(Integer likeUid){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        if(uid==null||null==likeUid||uid.equals(likeUid)){
            return R.error("喜欢失败");
        }
        UserDoingEntity userDoingEntity=new UserDoingEntity();
        userDoingEntity.setUid(uid.toString());
        //对象名称 user,post,comment
        userDoingEntity.setObjectName("user");
        userDoingEntity.setObjectId(likeUid);
        userDoingEntity.setObjectUid(likeUid.toString());
        userDoingEntity.setType("like");
        userDoingEntity.setUid(uid.toString());
        Object object=userSpaceService.likeUser(userDoingEntity);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok("操作成功").put("result",object);
    }

    /**
     * 上传设备信息
     * 用户登录以后上报一次 位置和设备信息
     * 1、GPS 位置信息
     * 2、IP地址
     * 3、设备平台
     * [ 上传设备信息 ] tb_user_location
     * @param ip IP地址
     * @param deviceType 客户端类型 android,ios,webapp
     * @param deviceDetailInfo 客户端信息 预留不用
     * @param lng 经度
     * @param lat 纬度
     * @return 返回成功
     */
    @Login
    @PostMapping("/update_device_info")
    @ApiOperation("上传设备信息 ")
    public R updateDeviceInfo(String ip,String deviceType,String deviceDetailInfo,String lng,String lat) {
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        UserLocationEntity userLocationEntity = new UserLocationEntity();
        userLocationEntity.setUid(uid.intValue());
        userLocationEntity.setIp(ip);
        userLocationEntity.setDeviceType(deviceType);
        userLocationEntity.setDeviceDetailInfo(deviceDetailInfo);
        userLocationEntity.setLng(lng);
        userLocationEntity.setLat(lat);
        Object object = userLocationService.updateUserLocation(userLocationEntity);

        if (object instanceof String) {
            return R.error(object.toString());
        }

        MixedOnlineUserEntity mouEntity = new MixedOnlineUserEntity();
        mouEntity.setUid(Integer.valueOf(uid.intValue()));
        mouEntity.setIp(ip);
        mouEntity.setLat(lat);
        mouEntity.setLng(lng);
        mouEntity.setLastUptime(mouEntity.getAdddate());
        mouEntity.setIsOnline(1);
        mixedOnlineUserService.updateById(mouEntity);

        return R.ok("操作成功");
    }

    /**
     * 举报动态
     * [ 举报动态] tb_user_report
     * @param entity
     * type 内容类型 post,user,chat
     * category 分类 举报原因，见UI举报列表
     * content 举报内容
     * ref 引用 posts/1100 代表编号为100的动态
     * @return 返回成功
     */
    @Login
    @PostMapping("/report")
    @ApiOperation("举报动态")
    public R report(UserReportEntity entity){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        entity.setUid(uid.intValue());
        Object object=userReportService.addReport(entity);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok("操作成功");
    }

    /**
     *形象照设置
     * 数据库 [ 用户信息表 ] tb_user_info
     * @param sense 形象照
     * @return
     */
    @Login
    @PostMapping("/user_sence_setting")
    @ApiOperation("形象照设置")
    public R userSenceSetting(String sense){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        if(StringUtils.isBlank(sense)){
            return R.error("请上传一张形象照");
        }
        UserInfoEntity userInfoEntity=new UserInfoEntity();
        userInfoEntity.setUid(uid.intValue());
        userInfoEntity.setSense(sense);
        //更新形象照
        userInfoService.updateUserInfo(userInfoEntity);
        return R.ok("保存成功");
    }

    /**
     *个人资料/增加标签
     * 数据库 [ 用户信息表 ] tb_user_info
     * @param tags 标签 各标签用逗号分隔
     * @return
     */
    @Login
    @SensitiveFilter
    @PostMapping("/update_user_tags")
    @ApiOperation("个人资料增加标签")
    public R updateUserTags(String tags){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        UserInfoEntity userInfoEntity=new UserInfoEntity();
        userInfoEntity.setUid(uid.intValue());
        userInfoEntity.setSense(tags);
        //更新形象照
        userInfoService.updateUserInfo(userInfoEntity);
        return R.ok("保存成功");
    }

    /**
     *个人资料/修改名字
     * 数据库 [ 用户信息表 ] tb_user_info
     * @param nikename 昵称
     * @return
     */
    @Login
    @SensitiveFilter
    @PostMapping("/update_user_nickname")
    @ApiOperation("个人资料修改名字 ")
    public R updateUserNickname(String nikename){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        //更新形象照
        Object object=userInfoService.updateUserNickname(uid,nikename);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok("保存成功");
    }

    /**
     *查看用户主页
     * 数据库 [ 用户信息表 ,用户空间表] tb_user_info,tb_user_space
     * @param uid 用户id
     * @return
     * 新增likeCount 喜欢数
     * isFlag : {
     *     isAttent:true, //是否关注
     *     isLike:true  //是否喜欢
     * }
     */
    @Login
    @GetMapping("/look_user_info")
    @ApiOperation("查看用户主页")
    public R lookUserInfo(Long uid){
        Long uId = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        if(uId==null){
            return R.error("请登录");
        }
        if(null==uid){
            return R.error("参数错误");
        }
        //查看用户主页信息
        ViewUserInfoSpaceEntity object=viewUserInfoSpaceService.getViewUserInfoSpace(uid);
        //添加查看行为
        UserDoingEntity userDoingEntity=new UserDoingEntity();
        userDoingEntity.setUid(uId.toString());
        userDoingEntity.setObjectUid(uid.toString());
        userDoingEntity.setObjectId(uid.intValue());
        userDoingEntity.setAdddate(DateUtils.getSecondTimestamp(new Date()));
        userDoingEntity.setObjectName("user");
        userDoingEntity.setType("look");
        userDoingService.addDoing(userDoingEntity);
        return R.ok(object).put("isFlag",chatFriendService.getIsAttentUserAndLikeUser(uId.intValue(),uid.intValue()));
    }


    /**
     *查看用户动态
     * 数据库 [ 用户信息表 ] tb_posts
     * @param page 页码
     * @param uid 用户id
     * @return
     */
    @Login
    @GetMapping("/look_user_posts")
    @ApiOperation("查看用户动态")
    public R lookUserPosts(Integer page,Long uid){
        Map<String,Object> para=new HashMap<>();
        para.put("page",page);
        para.put("limit",QuickHelper.getConfigString(SystemConfigName.RECORD_POST_PAGE_COUNT));
        para.put("uid",uid);
        List<String> viewPolicys=new ArrayList<>();
        viewPolicys.add("public");
        para.put("viewPolicys",viewPolicys);
        //查看用户动态
        Object object=postsService.getSpacePost(para);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok(object);
    }

    /**
     *聊天背景设置
     * 数据库 [ 用户空间表 ]  tb_user_space
     * @param chatBackground 聊天背景url
     * @return
     */
    @Login
    @PostMapping("/chat_background_setting")
    @ApiOperation("聊天背景设置 ")
    public R chatBackgroundSetting(String chatBackground){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        UserSpaceEntity entity=new UserSpaceEntity();
        entity.setUid(uid.intValue());
        entity.setBackgroundVoiceImage(chatBackground);
        userSpaceService.updateUserSpace(entity);
        return R.ok("操作成功");
    }

    private final List<String> categorys=Arrays.asList("coin","gift","vip");

    private final List<String> platforms=QuickHelper.getClassFiledNameArray(ConfigPaymentRateMoney2Coin.class);

    /**
     *  钱包充值
     * 数据库 [ 用户订单表  收支记录表]  tb_user_order tb_user_payment
     * @param paymentType 支付接口类型 alipay,weixin,other
     * @param amount 订单金额
     * @param subject 订单抬头
     * @param remark 订单备注内容
     * @param platform 客户端
     * @param type 类型 购买=buy,充值=recharget
     * @param objectName 购买金币=coin,购买礼物=gift,购买会员=vip
     * @param objectId 礼物id(购买礼物的时候需要传礼物id,其他传0)
     * @return
     */
    @Login
    @PostMapping("/recharge")
    @ApiOperation("钱包充值")
    public R recharge(String paymentType,String amount,String subject,String remark,String platform,String type,String objectName,String objectId){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        if(StringUtils.isBlank(paymentType)||amount==null
                ||StringUtils.isBlank(subject)||StringUtils.isBlank(platform)
                ||StringUtils.isBlank(type)||StringUtils.isBlank(objectName)){
            return R.error("参数有误");
        }
        if(!categorys.contains(objectName)){
            return R.error("objectName参数有误");
        }
        if(!platforms.contains(platform)){
            return R.error("platform参数有误");
        }
        UserOrderEntity entity=new UserOrderEntity();
        entity.setUid(uid.intValue());
        entity.setAmount(new BigDecimal(amount));
        entity.setPeymentType(paymentType);
        entity.setRemark(remark);
        entity.setObjectName(objectName);
        entity.setObjectId(objectId);
        entity.setState(0);
        entity.setPlatform(platform);
        entity.setSubject(subject);
        entity.setType(type);
        Object object=userOrderService.recharge(entity);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok(object);
    }

    /**
     *设置更换手机号
     * 数据库 [ 用户表 ]  tb_user
     * @return
     */
    @Login
    @PostMapping("/change_mobile")
    @ApiOperation("设置更换手机号 ")
    public R changeMobile(RegisterForm form){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        if(uid==null){
            return R.error("请登录");
        }
        //1.表单校验
        ValidatorUtils.validateEntity(form);

        String code = form.getValidateCode();
        String mobile = form.getMobile();

        //2.查询是否有获取过的短信
        if(!QuickHelper.getConfigValue(SystemConfigName.DEBUG,Boolean.class)) {
            ValidateCodeEntity codeEntity = validateCodeService.getLastValidCodeEntry(mobile, QuickHelper.getConfigIntegerValue(SystemConfigName.SMS_CONFIG_VALIDSECONDS));
            //检查验证码是否获取 ?
            if (codeEntity == null) {
                return R.error(-101, "手机验证码填写错误，请重新获取! ");
            }

            if (!codeEntity.getCode().equals(code)) {
                return R.error(-102, "手机验证码填写错误，请重新获取! ");
            }
        }
        userService.updateMobile(uid,mobile);
        return R.ok("操作成功");
    }

    /**
     *设置隐私设置
     * 数据库 [ 用户隐私策略 ]  tb_user_policy_setting
     * postSetting 动态策略 所有人=all,仅好友=friend,仅自己=self
     * chatSetting 聊天策略 保留不用
     * attentSetting 展示关注 允许=1，不允许=0
     * senceSetting 形象照策略 允许=1，不允许=0
     * @return
     */
    @Login
    @PostMapping("/change_policy")
    @ApiOperation("设置隐私设置")
    public R changePolicy(UserPolicySettingEntity entity){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        if(uid==null){
            return R.error("请登录");
        }
        entity.setUid(uid.intValue());
        userPolicySettingService.saveUserPoliy(entity);
        return R.ok("操作成功");
    }

    /**
     *获取隐私设置
     * 数据库 [ 用户隐私策略 ]  tb_user_policy_setting
     * postSetting 动态策略 所有人=all,仅好友=friend,仅自己=self
     * chatSetting 聊天策略 保留不用
     * attentSetting 展示关注 允许=1，不允许=0
     * senceSetting 形象照策略 允许=1，不允许=0
     * @return
     */
    @Login
    @GetMapping("/get_policy")
    @ApiOperation("获取隐私设置")
    public R getPolicy(){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        if(uid==null){
            return R.error("请登录");
        }
        return R.ok(userPolicySettingService.findUserPoliy(uid));
    }

    /**
     *直播设置封面
     * @param title 直播室标题
     * @param coverImage 直播室封面
     * 数据库 [ 用户隐私策略 ]  tb_live_room
     * @return
     */
    @Login
    @SensitiveFilter
    @PostMapping("/update_live_info")
    @ApiOperation("直播设置封面")
    public R updateLiveInfo(String title,String coverImage){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        //直播标题检测敏感词
        if(SensitiveUtil.containsSensitive(title)){
            return R.error("直播标题包含敏感词！");
        }

        LiveRoomEntity liveRoomEntity=new LiveRoomEntity();
        liveRoomEntity.setUid(uid.intValue());
        if(StringUtils.isNotBlank(title)){
            liveRoomEntity.setTitle(title);
        }
        if(StringUtils.isNotBlank(coverImage)){
            liveRoomEntity.setCoverImage(coverImage);
        }
        if(liveRoomService.updateById(liveRoomEntity)){
            return R.ok("操作成功");
        }
        return R.error("操作失败");
    }

    /**
     * 获取直播推流地址，不需要任何参数
     * @return
     * error 1=成功 -1401=禁播
     * url 推流地址
     * forbidden_msg 禁播公告
     * forbiden_time 禁播结束时间
     */
    @Login
    @GetMapping(value = "get_live_push_url")
    @ApiOperation("直播室推流地址")
    public R getLivePushUrl() {
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");

        LiveRoomEntity liveRoomEntity=liveRoomService.selectById(uid);
        if(liveRoomEntity!=null){
            if(liveRoomEntity.getState().intValue()<0){
                int forbidenTime=liveRoomEntity.getForbiddenEndTime();
                int time=DateUtils.getSecondTimestamp(new Date());
                if(forbidenTime>time){
                    Map<String,Object> map=new HashMap<>();
                    map.put("forbidden_msg",liveRoomEntity.getForbiddenMsg());
                    map.put("forbiden_end_time",forbidenTime);
                    return R.response(ResponseCode.FORBIDDEN_LIVE).put("data",map);
                }else{
                    LiveRoomEntity liveRoomEntity1=new LiveRoomEntity();
                    liveRoomEntity1.setUid(uid.intValue());
                    liveRoomEntity1.setState(0);
                    liveRoomService.updateById(liveRoomEntity1);
                }
            }
        }

        JSONObject obj = QuickHelper.getConfigJSONObject(SystemConfigName.ZHIBO_SDK_CONFIG);
        String active = obj.getString("active");
        JSONObject activeConfig = obj.getJSONObject("templateConfig").getJSONObject(active);

        //推流密钥
        String apikey = activeConfig.getString("ApiKey");

        //推流域名
        String pushDomain = activeConfig.getString("PushDomain");

        Integer expiredSeconds = DateUtils.getSecondTimestamp(new Date()) + 10 * 60 * 1000;
        String url = TencentLiveKit.getPushUrl(pushDomain, apikey, uid.toString(), expiredSeconds);

        return R.ok("获取成功").put("url", url);
    }

    /**
     * 获取直播播放地址
     * @param name 该参数为用户的 uid
     * @return
     */
    @GetMapping(value = "get_live_play_url")
    @ApiOperation("直播室播放地址")
    public R getLivePlayUrl(String name) {
        if(StringUtils.isBlank(name)){
            return R.error("参数错误");
        }
        LiveRoomEntity liveRoomEntity=liveRoomService.selectById(name);
        if(liveRoomEntity!=null){
            if(liveRoomEntity.getState().intValue()<0){
                int forbidenTime=liveRoomEntity.getForbiddenEndTime();
                int time=DateUtils.getSecondTimestamp(new Date());
                if(forbidenTime>time){
                    Map<String,Object> map=new HashMap<>();
                    map.put("forbidden_msg",liveRoomEntity.getForbiddenMsg());
                    map.put("forbiden_end_time",forbidenTime);
                    return R.response(ResponseCode.FORBIDDEN_LIVE).put("data",map);
                }else{
                    LiveRoomEntity liveRoomEntity1=new LiveRoomEntity();
                    liveRoomEntity1.setUid(Integer.parseInt(name));
                    liveRoomEntity1.setState(0);
                    liveRoomService.updateById(liveRoomEntity1);
                }
            }
        }

        JSONObject obj = QuickHelper.getConfigJSONObject(SystemConfigName.ZHIBO_SDK_CONFIG);
        String active = obj.getString("active");
        JSONObject activeConfig = obj.getJSONObject("templateConfig").getJSONObject(active);

        //推流密钥
        String apikey = activeConfig.getString("ApiKey");

        //播放域名
        String playDomain = activeConfig.getString("PlayDomain");
        Integer expiredSeconds = DateUtils.getSecondTimestamp(new Date()) + 10 * 60 * 1000;
        Map<String, String> map = new HashMap<>();
        map.put("FLV", String.format("http://%s/live/%s.flv", playDomain, name));
        map.put("RTMP", String.format("rtmp://%s/live/%s", playDomain, name));
        map.put("HLS", String.format("http://%s/live/%s.m3u8", playDomain, name));
        map.put("UDP", String.format(String.format("webrtc://%s/live/%s", playDomain, name)));
        return R.ok(map);
    }

    /**
     *获取我关注的人
     * 数据库 [ 用户信息表 ,用户行为表] tb_user_info,tb_user_doing
     * @param page 页码
     * @return
     *  "adddate": 0,
     *  "avanta": "http://app-dev-1301591806.cos.ap-shanghai.myqcloud.com/assets/user/defaultAvatar/102.png",
     *  "gender": 0,
     *  "ibo": "",
     *  "id": 117,
     *  "isLiked": 1, //是否细化 1=喜欢 2=未喜欢
     *  "nickname": "剑圣",
     *  "state": 1, //状态 已关注=1,陌生人=0,互相关注=2
     *  "objectUid": 11, //喜欢的人uid
     *  "uid": 3
     */
    @Login
    @GetMapping("/get_my_attent_users")
    @ApiOperation("获取我关注的人")
    public R getMyAttentUsers(Integer page){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        Map<String,Object> para=new HashMap<>();
        para.put("page",page.toString());
        para.put("limit",QuickHelper.getConfigString(SystemConfigName.RECORD_POST_PAGE_COUNT));
        para.put("uid",uid);
        //我关注的人
        para.put("states","1,2");
        //获取我关注的人
        Object object=viewChatFriendForTargetListService.queryPage(para);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok(object);
    }

    /**
     *获取我喜欢的人
     * 数据库 [ 用户信息表 ,用户行为表] tb_user_info,tb_user_doing
     * @param page 页码
     * @return
     *  "adddate": 0,
     *  "avanta": "http://app-dev-1301591806.cos.ap-shanghai.myqcloud.com/assets/user/defaultAvatar/102.png",
     *  "gender": 0,
     *  "ibo": "",
     *  "id": 117,
     *  "isLiked": 1, //是否细化 1=喜欢 2=未喜欢
     *  "nickname": "剑圣",
     *  "state": 1, //状态 已关注=1,陌生人=0,互相关注=2
     *  "objectUid": 11, //喜欢的人uid
     *  "uid": 3
     */
    @Login
    @GetMapping("/get_my_like_users")
    @ApiOperation("获取我喜欢的人 ")
    public R getMyLikeUsers(Integer page){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        Map<String,Object> para=new HashMap<>();
        para.put("page",page.toString());
        para.put("limit",QuickHelper.getConfigString(SystemConfigName.RECORD_POST_PAGE_COUNT));
        para.put("uid",uid);
        para.put("is_liked",1);
        //获取我喜欢的人
        Object object=viewChatFriendForTargetListService.queryPage(para);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok(object);
    }

    /**
     *获取关注我的人
     * 数据库 [ 用户信息表 ,用户行为表] tb_user_info,tb_user_doing
     * @param page 页码
     * @return
     *  "adddate": 0,
     *   "avanta": "https://app-dev-1301591806.cos.ap-shanghai.myqcloud.com/avatar/20201123/41117e33c91543f899572756471e20fd.jpeg",
     *  "gender": 0, //性别 1=男 0=女
     *  "ibo": "无敌是多么的寂寞",
     *  "id": 117,
     * "isLiked": 1,//是否细化 1=喜欢 2=未喜欢
     *  "nickname": "绿城彭于晏",
     *  "state": 1, //状态 已关注=1,陌生人=0,互相关注=2
     *  "objectUid": 11,
     *  "uid": 3 //关注我的uid
     */
    @Login
    @GetMapping("/get_attent_me_users")
    @ApiOperation("获取关注我的人")
    public R getAttentMeUsers(Integer page){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        Map<String,Object> para=new HashMap<>();
        para.put("page",page.toString());
        para.put("limit",QuickHelper.getConfigString(SystemConfigName.RECORD_POST_PAGE_COUNT));
        para.put("object_uid",uid);
        //我关注的人
        para.put("states","1,2");
        //获取关注我的人
        Object object=viewChatFriendListService.queryPage(para);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok(object);
    }


    /**
     *获取喜欢我的人
     * 数据库 [ 用户信息表 ,用户行为表] tb_user_info,tb_user_doing
     * @param page 页码
     * @return
     *  "adddate": 0,
     *   "avanta": "https://app-dev-1301591806.cos.ap-shanghai.myqcloud.com/avatar/20201123/41117e33c91543f899572756471e20fd.jpeg",
     *  "gender": 0, //性别 1=男 0=女
     *  "ibo": "无敌是多么的寂寞",
     *  "id": 117,
     * "isLiked": 1,//是否细化 1=喜欢 2=未喜欢
     *  "nickname": "绿城彭于晏",
     *  "state": 1, //状态 已关注=1,陌生人=0,互相关注=2
     *  "objectUid": 11,
     *  "uid": 3 //关注我的uid
     */
    @Login
    @GetMapping("/get_like_me_users")
    @ApiOperation("获取喜欢我的人")
    public R getLikeMeUsers(Integer page){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        Map<String,Object> para=new HashMap<>();
        para.put("page",page.toString());
        para.put("limit",QuickHelper.getConfigString(SystemConfigName.RECORD_POST_PAGE_COUNT));
        para.put("object_uid",uid);
        para.put("is_liked",1);
        //获取喜欢我的人
        Object object=viewChatFriendListService.queryPage(para);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok(object);
    }

    /**
     *获取我看过的人
     * 数据库 [ 用户信息表 ,用户行为表] tb_user_info,tb_user_doing
     * @param page 页码
     * @return
     */
    @Login
    @GetMapping("/get_my_look_users")
    @ApiOperation("获取我看过的人")
    public R getMyLookUsers(Integer page){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        Map<String,Object> para=new HashMap<>();
        para.put("page",page.toString());
        para.put("limit",QuickHelper.getConfigString(SystemConfigName.RECORD_POST_PAGE_COUNT));
        para.put("uid",uid);
        para.put("type","look");
        //获取喜欢我的人
        Object object=viewUserDoingGroupForObjectListService.queryPage(para);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok(object);
    }

    /**
     *获取看过我的人
     * 数据库 [ 用户信息表 ,用户行为表] tb_user_info,tb_user_doing
     * @param page 页码
     * @return
     */
    @Login
    @GetMapping("/get_look_me_users")
    @ApiOperation("获取看过我的人")
    public R getLookMeUsers(Integer page){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        Map<String,Object> para=new HashMap<>();
        para.put("page",page.toString());
        para.put("limit",QuickHelper.getConfigString(SystemConfigName.RECORD_POST_PAGE_COUNT));
        para.put("object_id",uid);
        para.put("type","look");
        //获取看过我的人
        Object object=viewUserDoingGroupListService.queryPage(para);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok(object);
    }

    /**
     *获取礼物背包
     * 数据库 [ 用户礼物] tb_user_gift
     * @param page 页码
     * @return
     * giftId 礼物编号
     * gift_price 购买时的价格
     * quantity 拥有数量
     * expire_date 过期时间
     * state 礼物状态
     */
    @Login
    @GetMapping("/get_my_gift_list")
    @ApiOperation("礼物背包")
    public R getMyGiftList(Integer page){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        Map<String,Object> para=new HashMap<>();
        para.put("page",page.toString());
        para.put("limit","8");
        para.put("uid",uid);
        //取礼物背包
        Object object=viewUserGiftListService.queryPage(para);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok(object);
    }

    /**
     *获取账单列表
     * 数据库 [ 用户礼物] tb_user_gift
     * @param type 购买=buy,充值=recharge ,退款=refound,提现余额=withdraw
     * @return
     * order_id 订单编号 订单表的ID
     * 购买=buy,充值=recharge,退款=refound,提现余额=withdraw
     * occur_value 发生金额 0
     * remark 备注
     * state 支付状态 支付成功=1
     */
    @Login
    @GetMapping("/get_payment_list")
    @ApiOperation("获取账单列表")
    public R getPaymentList(String type){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        Map<String,Object> para=new HashMap<>();
        para.put("uid",uid);
        para.put("type",type);
        //查看用户动态
        Object object=userPaymentService.getUserPaymentList(para);
        if(object instanceof String){
            return R.error(object.toString());
        }
        return R.ok(object);
    }

    /**
     *获取统计信息
     * @return
     * attented_count 我关注的人的数量
     * fans_count = 粉丝数（关注我的人的数量）
     * friend_count = 好友（chat_friend 表状态关于我的state=1的记录数）
     * my_look_count 我看过的
     * look_me_count 看过我的
     * my_like_count = 我喜欢的人数
     * like_me_count 喜欢我的人数
     */
    @Login
    @GetMapping("/stat_attent_info")
    @ApiOperation("获取统计信息")
    public R statAttentInfo(){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        return R.ok().put("data",viewUserDoingGroupForObjectListService.stateAttentAndLikeAndLook(uid.toString()));
    }

    private final List<String> giftMode=Arrays.asList("new","mode");

    /**
     *发送礼物
     * @param giftId 礼物id(背包里的礼物用背包列表id字段的数据)
     * @param quantity 礼物数量（默认为1)
     * @param targetUid 直播间播主uid
     * @param mode mode = new (礼物列表)|| mode = package（背包礼物）
     * @return
     * code -1201, "您的金币不足，无法购买
     * code 1 操作成功
     * code -1 操作失败
     */
    @Login
    @PostMapping("/send_gift")
    @ApiOperation("发送礼物")
    public R sendGift(String giftId,@RequestParam(defaultValue = "1") Integer quantity,String targetUid,@RequestParam(defaultValue = "new")String mode) {

        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");

        if(!giftMode.contains(mode)){
            return R.error("礼物模式未设置");
        }

        if(StringUtils.isBlank(giftId)){
            return R.error("礼物编号错误,请重新输入");
        }

        if(StringUtils.isBlank(targetUid)){
            return R.error("礼物接受人错误");
        }
        ResponseCode code;
        //是否是包裹礼物
        if ("mode".equals(mode)) {
            code=userService.sendUserGift(uid, giftId, quantity, targetUid);
        }else{
            code=userService.sendGift(uid, giftId, quantity, targetUid);
        }
        if(ResponseCode.SUCCESS.getCode().equals(code.getCode())) {
            //发送礼物通知
            UserInfoEntity userinfo = (UserInfoEntity) userInfoService.getInfo(uid, "info");
            Map<String, Object> data = new LinkedHashMap<>();
            data.put("giftId", giftId);
            data.put("uid", uid);
            data.put("quantity", quantity);
            data.put("nickname", userinfo.getNickname());
            data.put("avanta", userinfo.getAvanta());
            data.put("liveRoomUid", targetUid);
            MessagePacketData packetData = new MessagePacketData();
            packetData.setType(MessageType.REDIS_PROXY_MESSAGE_NEW_GIFT_EVENT);
            packetData.setContent(data);

            String str = QuickHelper.object2json(packetData);

            logger.info("========================= 发送赠送礼物事件到 redis =========================");
            logger.info(str);
            //将送礼物的消息发送到 redis
            int result = redisUtils.lSet(RedisConstKey.REDIS_PROXY_MESSAGE_KEY, packetData);
        }
        return R.response(code);
    }

    @Login
    @PostMapping("/send_gift2")
    @ApiOperation("发送礼物")
    public R sendGift2(@RequestParam(defaultValue = "-1") Integer giftId,@RequestParam(defaultValue = "1") Integer quantity,String targetUid,@RequestParam(defaultValue = "new")String mode) {

        Long uid = HttpContextUtils.getHttpServletRequestHeaderUserid();

        if (!giftMode.contains(mode)) {
            return R.error("礼物模式未设置");
        }

        if (giftId < 0) {
            return R.error("礼物编号错误,请重新输入");
        }

        if (!StringUtils.isBlank(targetUid)) {
            return R.error("礼物接受人错误");
        }

        ResponseCode code = ResponseCode.NONE;

        //如果从背包送出
        if ("mode".equals(mode)) {
            code = userService.sendGift2LiveRoom(uid, giftId, quantity, targetUid);
        } else {
            code = userService.sendGift2LiveRoom(uid, giftId, quantity, targetUid);
        }

        if(ResponseCode.SUCCESS.getCode().equals(code.getCode())){
            UserInfoEntity userinfo = (UserInfoEntity) userInfoService.getInfo(uid, "info");
            Map<String, Object> data = new LinkedHashMap<>();
            data.put("giftId", giftId);
            data.put("uid", uid);
            data.put("quantity", quantity);
            data.put("nickname", userinfo.getNickname());
            data.put("avanta", userinfo.getAvanta());
            data.put("liveRoomUid", targetUid);
            MessagePacketData packetData = new MessagePacketData();
            packetData.setType(MessageType.REDIS_PROXY_MESSAGE_NEW_GIFT_EVENT);
            packetData.setContent(data);

            String str = QuickHelper.object2json(packetData);

            logger.info("========================= 发送赠送礼物事件到 redis =========================");
            logger.info(str);

            //将送礼物的消息发送到 redis
            int result = redisUtils.lSet(RedisConstKey.REDIS_PROXY_MESSAGE_KEY, packetData);
        }
        return R.response(code);
    }

    /**
     *获取银行卡列表
     * @return
     * bankName 银行名称
     * bankAddress = 开户地址
     * bankNo = 卡号后4位
     * bankImage =银行图标
     */
    @Login
    @GetMapping("/get_bank_list")
    @ApiOperation("获取银行卡列表")
    public R getBankList(){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        List<UserBankEntity> userBankEntities=userBankService.selectList(new EntityWrapper<UserBankEntity>().eq("uid",uid));
        ConfigServers servers = QuickHelper.getConfigValue(SystemConfigName.SERVERS, ConfigServers.class);
        String imageUrl=servers.getFrontServer()+"/html/static/bank/DEFAULT.png";
        JSONArray jsonArray=QuickHelper.getConfigJSONObject(SystemConfigName.PAY_WITHDRAW_CONFIG).getJSONArray("list");
        List<Map<String,Object>> result=new ArrayList<>(userBankEntities.size());
        for(UserBankEntity userBankEntity:userBankEntities){
            Map<String,Object> temp=new HashMap<>();
            temp.put("id",userBankEntity.getId());
            String bankNo=userBankEntity.getBankNo();
            temp.put("bankNo",bankNo.substring(bankNo.length()-4));
            temp.put("bankName",userBankEntity.getBankName());
            String bankCode=userBankEntity.getBankCode();
            temp.put("bankImage",jsonArray.contains(bankCode)?imageUrl.replace("DEFAULT",bankCode):imageUrl);
            result.add(temp);
        }
        return R.ok(result);
    }

    /**
     *添加银行卡
     * @param bankMobile 银行预留手机号
     * @param bankNo 卡号
     * @param bankRealName 开户人
     * @param idCard 身份证号
     * @return
     * code -1 信息有误
     *  -1302 当前用户实名认证与所银行卡所有者不一致
     */
    @Login
    @PostMapping("/add_bank_item")
    @ApiOperation("添加银行卡")
    public R getBankItem(String bankRealName,String bankMobile,String bankNo,String idCard){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        if(StringUtils.isBlank(bankRealName)||StringUtils.isBlank(bankMobile)
                ||StringUtils.isBlank(bankNo)
                ||StringUtils.isBlank(idCard)){
            return R.response(ResponseCode.FAIL,"信息有误");
        }

        //1.判断实名认证的真实姓名是否与银行卡四要素验证的返回的姓名一致
        UserInfoEntity userInfoEntity=userInfoService.selectById(uid);
        if(null==userInfoEntity){
            return R.error("请登录");
        }
        if(!bankRealName.equals(userInfoEntity.getRealname())){
            return R.response(ResponseCode.ERROR_DIFFERENT_NAME);
        }
        //2.判断是否支持的银行
        String strBankSdkCodes=QuickHelper.getConfigString(SystemConfigName.BANK_SDK_CODES);
        Object object=JuheDataApiHelper.verifyBankCard(bankNo,QuickHelper.getConfigString(SystemConfigName.PAY_WITHDRAW_CONFIG),strBankSdkCodes);
        if(object instanceof String){
            return R.response(ResponseCode.FAIL,object.toString());
        }
        JSONObject jsonObject=(JSONObject)object;

        //3.判断四要素
        ConfigJuheSdk configJuheSdk = QuickHelper.getConfigValue(SystemConfigName.JUHE_SDK_CONFIG, ConfigJuheSdk.class);
        String url="http://v.juhe.cn/verifybankcard4/query?key={SDKKey}&bankcard={bankNo}&realname={bankRealName}&idcard={idCard}&mobile={bankMobile}"
                .replace("{SDKKey}",configJuheSdk.getVerifybankcard4()).replace("{bankRealName}",bankRealName).replace("{bankMobile}",bankMobile)
                .replace("{bankNo}",bankNo).replace("{idCard}",idCard);
        logger.info(url);

        try {
            OkHttpClient httpClient = new OkHttpClient();
            Request request = new Request.Builder().url(url)
                    .addHeader("custon-header", "Basic ")
                    .build();
            Response res = httpClient.newCall(request).execute();
            String str = res.body().string();
            logger.info(str);
            JSONObject obj = QuickHelper.json2object(str, JSONObject.class);
            logger.info(QuickHelper.object2json(obj));
            if(obj.getIntValue("error_code")!=0||!obj.containsKey("result")){
                return R.response(ResponseCode.FAIL,"系统错误，请稍后再试");
            }
            JSONObject result=obj.getJSONObject("result");
            if("2".equals(result.getString("res"))){
                return R.response(ResponseCode.ERROR_VERIFYBANKCARD4_MISMATCH);
            }
        }catch (Exception e){
            return R.error("获取失败");
        }

        UserBankEntity userBankEntity=new UserBankEntity();
        userBankEntity.setUid(uid.toString());
        userBankEntity.setBankCode(jsonObject.getString("bankCode"));
        userBankEntity.setBankName(jsonObject.getString("bankName"));
        userBankEntity.setBankNo(bankNo);
        userBankEntity.setBankMobile(bankMobile);
        userBankEntity.setIdcard(idCard);
        userBankEntity.setBankRealname(bankRealName);
        userBankEntity.setAdddate(DateUtils.format(new Date(),DateUtils.DATE_TIME_PATTERN));
        userBankService.insert(userBankEntity);
        return R.ok();
    }

    /**
     *检查银行卡编码
     * @param bankNo 银行卡号
     * @return
     * 返回 bankCode 银行code
     * bankName 银行名字
     */
    @Login
    @PostMapping("/verify_bank_card")
    @ApiOperation("检查银行卡编码")
    public R verifyBankCard(String bankNo) {
        if(StringUtils.isBlank(bankNo)){
            return R.response(ResponseCode.FAIL,"银行卡号有误");
        }
        String strBankSdkCodes=QuickHelper.getConfigString(SystemConfigName.BANK_SDK_CODES);
        Object object=JuheDataApiHelper.verifyBankCard(bankNo,QuickHelper.getConfigString(SystemConfigName.PAY_WITHDRAW_CONFIG),strBankSdkCodes);
        if(object instanceof String){
            return R.response(ResponseCode.FAIL,"还不支持该银行卡");
        }
        return R.ok().put("data",object);
    }

    /**
     *删除银行卡
     * @param id 银行卡id
     * @return
     */
    @Login
    @PostMapping("/delete_bank_item")
    @ApiOperation("删除银行卡")
    public R deleteBankItem(Integer id){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        if(id==null){
            return R.response(ResponseCode.FAIL,"参数有误");
        }
        userBankService.delete(new EntityWrapper<UserBankEntity>().eq("id",id).eq("uid",uid));
        return R.ok();
    }

    /**
     *我的收入
     * @return
     * "adddate": 0,
     * "id": 1,
     * "incomeMoney": 0,//收益金额
     * "state": 0,//状态 1=已结算,0=未结算,-1=失效
     * "type": "live",//收益类型 直播=live,礼物=gift,红包=red_packet
     * "uid": 4
     */
    @Login
    @GetMapping("/get_my_income")
    @ApiOperation("我的收入")
    public R getMyIncome(){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        JSONObject jsonObject=QuickHelper.getConfigJSONObject(SystemConfigName.ASSETS_INCOME_TYPEDEFINED);
        List<UserIncomeHistoryEntity> userIncomeHistoryEntities=new ArrayList<>(jsonObject.keySet().size());
        Map<String,UserIncomeHistoryEntity> userIncomeHistoryEntityMap=userIncomeHistoryService.getMyIncome(uid.intValue());
        for(String type:jsonObject.keySet()){
            if(!userIncomeHistoryEntityMap.containsKey(type)){
                UserIncomeHistoryEntity userIncomeHistoryEntity=new UserIncomeHistoryEntity();
                userIncomeHistoryEntity.setIncomeMoney(BigDecimal.ZERO);
                userIncomeHistoryEntity.setUid(uid.intValue());
                userIncomeHistoryEntity.setState(0);
                userIncomeHistoryEntity.setType(type);
                userIncomeHistoryEntities.add(userIncomeHistoryEntity);
            }else{
                userIncomeHistoryEntities.add(userIncomeHistoryEntityMap.get(type));
            }
        }
        return R.ok(userIncomeHistoryEntities);
    }

    /**
     *申请提现
     * @param bankId 银行卡id
     * @param amount 提现金额
     * @param type 提现方式 bank=银行
     * @return
     */
    @Login
    @PostMapping("/add_withdraw_request")
    @ApiOperation("申请提现")
    public R addWithdrawRequest(String bankId,String type,String amount){

        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        if(StringUtils.isBlank(bankId)||!StringUtils.isNumeric(amount)){
            return R.response(ResponseCode.FAIL,"参数有误");
        }
        //转换金额类型
        BigDecimal amou=new BigDecimal(amount);
        //获取提现配置信息
        JSONObject jobject=QuickHelper.getConfigJSONObject(SystemConfigName.PAY_WITHDRAW_CONFIG);
        if(!jobject.containsKey("limit")){
            return R.response(ResponseCode.FAIL,"系统参数错误，请稍后再试");
        }
        JSONObject limitObject =jobject.getJSONObject("limit");
        BigDecimal max=limitObject.getBigDecimal("max");
        BigDecimal min=limitObject.getBigDecimal("min");
        if(max.compareTo(amou)!=1){
            return R.response(ResponseCode.FAIL,String.format("最大提现金额%s",max));
        }
        if(min.compareTo(amou)==1){
            return R.response(ResponseCode.FAIL,String.format("最小提现金额%s",min));
        }

        UserBankEntity userBankEntity=userBankService.selectOne(new EntityWrapper<UserBankEntity>().eq("id",bankId).eq("uid",uid));
        if(userBankEntity==null){
            return R.response(ResponseCode.FAIL,"银行卡信息有误，请重新添加");
        }
        UserBalanceEntity userBalanceEntity=userBalanceService.selectById(uid);
        BigDecimal balance=userBalanceEntity.getBalance();

        if(balance.compareTo(amou)==-1){
            return R.response(ResponseCode.ERROR_BALANCE_IS_NOT_ENOUGH);
        }
        UserWithdrawHistoryEntity userWithdrawHistoryEntity=new UserWithdrawHistoryEntity();
        userWithdrawHistoryEntity.setAdddate(DateUtils.getSecondTimestamp(new Date()));
        userWithdrawHistoryEntity.setBankName(userBankEntity.getBankName());
        userWithdrawHistoryEntity.setBankNo(userBankEntity.getBankNo());
        userWithdrawHistoryEntity.setBankRealname(userBankEntity.getBankRealname());
        userWithdrawHistoryEntity.setState(0);
        userWithdrawHistoryEntity.setType(type);
        userWithdrawHistoryEntity.setWithdrawMoney(new BigDecimal(amount));
        userWithdrawHistoryEntity.setUid(uid.intValue());
        userWithdrawHistoryService.insert(userWithdrawHistoryEntity);
        return R.ok("提现申请成功，1-2个工作日内到账");
    }

    /**
     *提现记录
     * @param page 页码
     * @return
     * type 提现方式 bank=银行
     * withdraw_money = 提现金额
     * bank_name = 开户行
     * bank_realname 户名
     * bank_no 卡号
     * state 审核状态 -1=审核失败,0=审核中,1=提现成功
     * adddate
     */
    @Login
    @GetMapping("/get_withdraw_list")
    @ApiOperation("提现记录")
    public R getWithdrawlist(Integer page){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        Map<String,Object> para=new HashMap<>();
        para.put("page",page.toString());
        para.put("limit",QuickHelper.getConfigString(SystemConfigName.RECORD_USER_RECHARGE_PAGE_COUNT));
        para.put("uid",uid);
        return R.ok(userWithdrawHistoryService.queryPage(para));
    }

    /**
     *实名认证
     * @param realName 真实姓名
     * @param idCard 身份证号
     * @return
     */
    @Login
    @PostMapping("/verify_user_idcard")
    @ApiOperation("实名认证")
    public R verifyUserIdcard(String realName,String idCard){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        if(StringUtils.isBlank(realName)||StringUtils.isBlank(idCard)){
            return R.response(ResponseCode.FAIL,"参数有误");
        }
        ConfigJuheSdk configJuheSdk = QuickHelper.getConfigValue(SystemConfigName.JUHE_SDK_CONFIG, ConfigJuheSdk.class);
        //身份认证
        String url="http://op.juhe.cn/idcard/query?key={SDKKey}&idcard={idCard}&realname={realName}"
                .replace("{SDKKey}",configJuheSdk.getIdcard()).replace("{realName}",realName).replace("{idCard}",idCard);
        logger.info(url);

        try {
            OkHttpClient httpClient = new OkHttpClient();
            Request request = new Request.Builder().url(url)
                    .addHeader("custon-header", "Basic ")
                    .build();
            Response res = httpClient.newCall(request).execute();
            String str = res.body().string();

            int nowTime=DateUtils.getSecondTimestamp(new Date());
            //组装实名记录
            IdcardVerifyHistoryEntity idcardVerifyHistoryEntity=new IdcardVerifyHistoryEntity();
            idcardVerifyHistoryEntity.setIdcard(idCard);
            idcardVerifyHistoryEntity.setUid(uid.intValue());
            idcardVerifyHistoryEntity.setRaw(str);
            idcardVerifyHistoryEntity.setRealname(realName);
            idcardVerifyHistoryEntity.setVerifydate(nowTime);
            idcardVerifyHistoryEntity.setAdddate(nowTime);

            JSONObject obj = QuickHelper.json2object(str, JSONObject.class);
            logger.info(QuickHelper.object2json(obj));
            if(obj.getIntValue("error_code")!=0||!obj.containsKey("result")){
                return R.response(ResponseCode.FAIL,obj.getString("reason"));
            }

            JSONObject result=obj.getJSONObject("result");
            if("1".equals(result.getString("res"))){
                UserInfoEntity userInfoEntity=new UserInfoEntity();
                userInfoEntity.setUid(uid.intValue());
                userInfoEntity.setIdcard(idCard);
                userInfoEntity.setRealname(realName);
                userInfoEntity.setIsVerifyIdcard(1);
                //插入实名记录
                idcardVerifyHistoryEntity.setState(1);
                idcardVerifyHistoryService.insert(idcardVerifyHistoryEntity);

                return R.ok().put("result",userInfoService.updateById(userInfoEntity));
            }
            //插入实名记录
            idcardVerifyHistoryEntity.setState(0);
            idcardVerifyHistoryService.insert(idcardVerifyHistoryEntity);
            return R.response(ResponseCode.ERROR_VERIFYBANKCARD4_MISMATCH);
        }catch (Exception e){
            return R.error("获取失败");
        }
    }


    /**
     *提现到余额
     * @param type  live=直播收入, gift=礼物收入, red_packet=红包收入
     * @return
     */
    @Login
    @PostMapping("/update_income2balance")
    @ApiOperation("提现到余额")
    public R updateIncome2balance(String type){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        if(StringUtils.isBlank(type)){
            return R.response(ResponseCode.FAIL,"参数有误");
        }
        Object object=userIncomeHistoryService.updateIncome2balance(type,uid);
        if(object instanceof String){
            return R.response(ResponseCode.FAIL,object.toString());
        }
        return R.ok("转到余额成功");
    }

    /**
     *余额转金币
     * @param amount  余额
     * @return
     */
    @Login
    @PostMapping("/update_blance2coin")
    @ApiOperation("余额转金币")
    public R updateBlance2coin(String amount){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        if(!StringUtils.isNumeric(amount)){
            return R.response(ResponseCode.FAIL,"参数有误");
        }
        Object object=userIncomeHistoryService.updateBlance2coin(Integer.parseInt(amount),uid);
        if(object instanceof String){
            return R.response(ResponseCode.FAIL,object.toString());
        }
        return R.ok("转到金币成功");
    }

    /**
     *更新标签
     * @param tag  标签,不同标签以逗分隔
     * @return
     */
    @Login
    @SensitiveFilter
    @PostMapping("/update_tag_item")
    @ApiOperation("更新标签")
    public R addTagItem(String tag){
        //标签敏感词检测
        if(SensitiveUtil.containsSensitive(tag)){
            return R.error("标签中包含敏感词！");
        }

        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        UserInfoEntity userInfoEntity=new UserInfoEntity();
        userInfoEntity.setUid(uid.intValue());
        userInfoEntity.setTags(tag);
        userInfoService.updateById(userInfoEntity);
        return R.ok("更新标签成功");
    }

    /**
     *获取用户匹配服务
     * @return
     *  "dailyInterestSearchCount": 30,//兴趣匹配次数
     * "dailyLocationSearchCount": 30,//定位匹配次数
     * "dailySenceSearchCount": 30,//形象匹配次数
     * "dailyVoiceSearchCount": 30,//语音匹配次数
     * "expireDate": 0,//会员到期时间
     * "isVip": 0,//是否是VIP 是=1,否=0
     * "lastModifyDate": 0,//更新时间
     * "uid": 4
     */
    @Login
    @PostMapping("/get_user_vip_info")
    @ApiOperation("获取用户匹配服务")
    public R getUserVipInfo(){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        return R.ok(userVipinfoService.selectById(uid));
    }

    /**
     *直播室打赏榜
     * @param liveRoundId 直播室场次id
     * @return
     * "avanta": "https://app-dev-1301591806.cos.ap-shanghai.myqcloud.com/avatar/20201118/9fcb1a1ecf15469c8343e4488884b69d.jpg",
     * "fromUid": 2, //发送礼物的人uid
     * "nickname": "宇宙第一帅",//发送礼物的人的昵称
     * "totalCoin": 83,//发送的总的金币
     * "uid": 4  //主播uid
     *
     */
    @Login
    @PostMapping("/get_rewards_top_list")
    @ApiOperation("直播室打赏榜")
    public R getRewardsTopList(String liveRoundId){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        if(StringUtils.isBlank(liveRoundId)){
            return R.response(ResponseCode.FAIL,"请传人直播室场次id");
        }
        return R.ok(liveRewardsService.getRewardsTopList(liveRoundId));
    }

    /**
     * @param urls 图片地址jsonArray ["url","url1"]
     *添加照片
     * @return
     */
    @Login
    @PostMapping("/upload_photo")
    @ApiOperation("添加照片")
    public R uploadPhoto(String urls){
        String uid = HttpContextUtils.getHttpServletRequestHeaderValue("uid").toString();
        if(StringUtils.isBlank(urls)){
            return R.response(ResponseCode.FAIL,"无上传图片");
        }

        JSONArray jsonArray=JSONArray.parseArray(urls);
        List<PhotosEntity> photosEntities=new ArrayList<>(jsonArray.size());
        Integer time=DateUtils.getSecondTimestamp(new Date());

        for(int i=0;i<jsonArray.size();i++){
            PhotosEntity photosEntity=new PhotosEntity();
            photosEntity.setUrl(jsonArray.getString(i));
            photosEntity.setDisplayorder(i);
            photosEntity.setUid(uid);
            photosEntity.setAdddate(time);
            photosEntities.add(photosEntity);
        }
        return R.ok(photosService.insertBatch(photosEntities));
    }

    /**
     *删除照片
     * @param photoId 相片id
     * @return
     */
    @Login
    @PostMapping("/delete_photo")
    @ApiOperation("删除照片")
    public R deletePhoto(String photoId){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        if(StringUtils.isBlank(photoId)){
            return R.response(ResponseCode.FAIL,"缺少相片id");
        }
        photosService.delete(new EntityWrapper<PhotosEntity>().eq("uid",uid).eq("id",photoId));
        return R.ok();
    }

    /**
     *我的相片
     * @return
     */
    @Login
    @GetMapping("/get_my_photo_list")
    @ApiOperation("我的相片")
    public R getMyPhotoList(){
        Long uid = (Long) HttpContextUtils.getHttpServletRequestHeaderValue("uid");
        return R.ok(photosService.selectList(new EntityWrapper<PhotosEntity>().eq("uid",uid).orderBy("displayorder",false)));
    }

    /**
     *他人主页相册
     * @param uid 他人uid
     * @return
     */
    @Login
    @GetMapping("/get_photo_list")
    @ApiOperation("他人主页相册")
    public R getPhotoList(String uid){
        return R.ok(photosService.selectList(new EntityWrapper<PhotosEntity>().eq("uid",uid).ge("displayorder",0).orderBy("displayorder",false)));
    }


    /**
     * 获取实时语音的 token
     * @return
     */
    @Login
    @GetMapping("/get_single_voice_token")
    @ApiOperation("获取语音聊天token")
    public R getAgoraRtcToken(@RequestParam(value = "channelId",defaultValue = "") String channelId) {
        Long uid = HttpContextUtils.getHttpServletRequestHeaderUserid();
        ConfigAgoraSdk sdkConfig = QuickHelper.getConfigValue("sys.agora.sdk.config", ConfigAgoraSdk.class);
        if(StringUtils.isBlank(channelId)){
            return R.error("加入的频道ID为空");
        }
        if("create".equals(channelId)){
            channelId = UUID.randomUUID().toString();
        }

        String channelName = channelId;
        Integer expiredSeconds = sdkConfig.getExpiredSeconds();
        String appId = sdkConfig.getAppId();
        String appCertificate = sdkConfig.getAppCertificate();
        String token = AgoraHelper.createRtcToken(channelName, uid.intValue(), expiredSeconds, appId, appCertificate);
        Map<String, String> data = QuickHelper.createMap("token", token);
        data.put("uid", uid.toString());
        data.put("appid", sdkConfig.getAppId());
        data.put("channelId", channelId);
        return R.ok().put("data", data);
    }
}
